package com.woniu.car.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.car.client.CouponsClient;
import com.woniu.car.common.ResponseEntity;
import com.woniu.car.dto.CouponUseDto;
import com.woniu.car.dto.ServerOrderDto;
import com.woniu.car.dto.constant.CommonConstant;
import com.woniu.car.entity.TServerDetail;
import com.woniu.car.entity.TServerOrder;
import com.woniu.car.entity.TService;
import com.woniu.car.exception.ParamException;
import com.woniu.car.mapper.TServerOrderMapper;
import com.woniu.car.param.OrderDetailParam;
import com.woniu.car.service.TServerDetailService;
import com.woniu.car.service.TServerOrderService;
import com.woniu.car.service.TServiceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author *********
 * @since 2021-06-21
 */
@Service
@Slf4j
public class TServerOrderServiceImpl extends ServiceImpl<TServerOrderMapper, TServerOrder> implements TServerOrderService {

    @Resource
    private RedissonClient redissonClient;
    @Resource
    private RocketMQTemplate rocketMQTemplate;
    @Resource
    private TServiceService tServiceService;
    @Resource
    private TServerDetailService tServerDetailService;
    @Resource
    private CouponsClient couponsClient;

    /**
    *@Author 李磊
    *@Description 新增订单(以及订单详情新增)
    *@Param [list, id]
    *@return com.woniu.car.dto.ServerOrderDto
    **/
    @Transactional
    @Override
    public ServerOrderDto insertOrder(List<OrderDetailParam> list, int id) throws InterruptedException {

        if (null == list || list.size() <= 0 || null == list.get(0)) {
            throw new ParamException(CommonConstant.PROCESSNULL);
        }

        for (OrderDetailParam orderDetailParam : list) {
            TService byId = tServiceService.getById(orderDetailParam.getServerId());
            if (null == byId) {
                throw new ParamException(CommonConstant.COWRONG);
            }
            if (!byId.getStatus().equals(CommonConstant.ONE)) {
                throw new ParamException(CommonConstant.COWRONG);
            }
        }

        double total = 0;

        //生成订单编号
        String code = UUID.randomUUID().toString();

        TServerOrder order = new TServerOrder();
        order.setOrderNumber(code);
        order.setUserId(id);
        order.setTotal(total);

        //上锁
        RLock lock = redissonClient.getLock("order:lock:" + code);

        boolean res = lock.tryLock(10, 5, TimeUnit.SECONDS);
        if (res) {
            try {
                this.save(order);
            } finally {
                lock.unlock();
            }
        }

        //订单详情新增
        for (OrderDetailParam orderDetailParam : list) {
            TService byId = tServiceService.getById(orderDetailParam.getServerId());

            TServerDetail detail = new TServerDetail();
            detail.setServerId(byId.getServiceId());
            detail.setPrice(byId.getServicePrice());
            detail.setNumber(orderDetailParam.getNumber());
            detail.setShopId(byId.getShopId());
            detail.setServerName(byId.getServiceName());
            double total1 = detail.getPrice() * detail.getNumber();

            //使用优惠券
            if (null != orderDetailParam.getCouponsId()) {

                ResponseEntity<CouponUseDto> responseEntity = couponsClient.couponUseCoupon(orderDetailParam.getCouponsId());
                CouponUseDto couponUseDto = responseEntity.getObject();

                if (null == couponUseDto) {
                    throw new ParamException(CommonConstant.COUPONWRONG);
                }

                if (couponUseDto.getUserId() != id) {
                    throw new ParamException(CommonConstant.COUPONUSERWRONG);
                }

                if (couponUseDto.getDiscountMoney() == 0) {
                    if (detail.getPrice()*detail.getNumber() < couponUseDto.getDeductionMoney()) {
                        throw new ParamException(CommonConstant.COUPONNOFULL);
                    }
                    detail.setFullMoney(couponUseDto.getFullMoney());
                    total1 = detail.getPrice()*detail.getNumber() - couponUseDto.getFullMoney();
                } else {
                    total1 = detail.getPrice()*detail.getNumber() * couponUseDto.getDiscountMoney();
                    detail.setDiscountMoney(couponUseDto.getDiscountMoney());
                }
            }

            //生成订单详情编号
            String code1 = UUID.randomUUID().toString();
            detail.setDetailNumber(code1);
            detail.setTotal(total1);
            detail.setOrderId(order.getOrderId());

            //新增订单详情
            tServerDetailService.save(detail);

            total = total + total1;
        }




        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("order_number",code);
        TServerOrder byId = this.getOne(wrapper);

        byId.setTotal(total);
        this.updateById(byId);

        ServerOrderDto serverOrderDto = new ServerOrderDto();
        BeanUtils.copyProperties(byId,serverOrderDto);

        //延迟消息更新订单状态
        Message msg = MessageBuilder.withPayload(byId.getOrderId()).build();
        rocketMQTemplate.syncSend("service:order",msg,30000,15);

        return serverOrderDto;
    }



}
